using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.IO;


namespace Petra.Gis.DataServices.SHP
{
	/// <summary>
	/// Class that allows records in a dbase file to be enumerated.
	/// </summary>
	public partial class DbaseFileReader  : IEnumerable
	{

    //ArrayList _arrayList;
    uint _currentRecord = 0;
    private BinaryReader br = null;
    //private int _readPosition = 0;
    protected string[] _fieldNames = null;



    //private DateTime _lastUpdate;
    //private int _NumberOfRecords;
    //private Int16 _HeaderLength;
    //private Int16 _RecordLength;
    //private DbaseField[] _dbaseColumns;
    //private FileStream fs;


			#region Implementation of IEnumerator




      //protected void Reset()
      //{
      //  _readPosition = _header.HeaderLength;
      //  _iCurrentRecord = 0;
      //}
 




      //protected void ReadHeader()
      //{
      //  _header = new DbaseHeader();
      //  // read the header
      //  _header.ReadHeader(br);

      //  // how many records remain
      //  _readPosition = _header.HeaderLength;
      //}











      ///// <summary>
      ///// Read a single dbase record
      ///// </summary>
      ///// <returns>return the read shapefile record or null if there are no more records</returns>
      //private bool Read()
      //{

      //  _iCurrentRecord++;

      //  if (_iCurrentRecord > _header.NumRecords)
      //  {
      //    br.Close();
      //    return false;
      //  }


      //  //ArrayList attrs = null;
       
      //  bool foundRecord = false;
      //  while (!foundRecord) 
      //  {
      //    // retrieve the record length
      //    int tempNumFields = _header.NumFields;
            
      //    // storage for the actual values
      //    recordData = new ArrayList(tempNumFields);
            
      //    // read the deleted flag
      //    char tempDeleted = (char)br.ReadChar();
            
      //    // read the record length
      //    int tempRecordLength = 1; // for the deleted character just read.
            
      //    // read the Fields
      //    for (int j = 0; j < tempNumFields; j++)
      //    {                
      //      // find the length of the field.
      //      int tempFieldLength = _header.Fields[j].Length;
      //      tempRecordLength = tempRecordLength + tempFieldLength;
                
      //      // find the field type
      //      char tempFieldType = _header.Fields[j].DbaseType;
                
      //      // read the data.
      //      object tempObject = null;
      //      switch (tempFieldType)
      //      {
      //        case 'L':   // logical data type, one character (T,t,F,f,Y,y,N,n)
      //          char tempChar = (char)_dbfStream.ReadByte();
      //          if ((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y'))
      //             tempObject = true;
      //          else tempObject = false;
      //          break;

      //        case 'C':   // character record.
      //          char[] sbuffer = new char[tempFieldLength];
      //          sbuffer = _dbfStream.ReadChars(tempFieldLength);
      //          // use an encoding to ensure all 8 bits are loaded
      //          // tempObject = new string(sbuffer, "ISO-8859-1").Trim();								

      //          //HACK: this can be made more efficient
      //          tempObject = new string(sbuffer).Trim().Replace("\0",String.Empty);   //.ToCharArray();
      //          break;
                        
      //        case 'D':   // date data type.
      //          char[] ebuffer = new char[8];
      //          ebuffer = _dbfStream.ReadChars(8);
      //          string tempString = new string(ebuffer, 0, 4);
      //          int year = Int32.Parse(tempString, CultureInfo.InvariantCulture);
      //          tempString = new string(ebuffer, 4, 2);
      //                          int month = Int32.Parse(tempString, CultureInfo.InvariantCulture);
      //          tempString = new string(ebuffer, 6, 2);
      //          int day = Int32.Parse(tempString, CultureInfo.InvariantCulture);
      //          tempObject = new DateTime(year, month, day);
      //          break;
                        
      //        case 'N': // number
      //        case 'F': // floating point number
      //          char[] fbuffer = new char[tempFieldLength];
      //          fbuffer = _dbfStream.ReadChars(tempFieldLength);
      //          tempString = new string(fbuffer);
      //          try 
      //          { 
      //            tempObject = Double.Parse(tempString.Trim(), CultureInfo.InvariantCulture);
      //          }
      //          catch (FormatException) 
      //          {
      //            // if we can't format the number, just save it as a string
      //            tempObject = tempString;
      //          }
      //          break;
                        
      //        default:
      //          throw new NotSupportedException("Do not know how to parse Field type "+tempFieldType);
      //      }
      //      recordData.Add(tempObject);
      //    }
            
      //    // ensure that the full record has been read.
      //    if (tempRecordLength < _header.RecordLength)
      //    {
      //      byte[] tempbuff = new byte[_header.RecordLength-tempRecordLength];
      //      tempbuff = _dbfStream.ReadBytes(_header.RecordLength-tempRecordLength);
      //    }
            
      //    // add the row if it is not deleted.
      //    if (tempDeleted != '*')
      //    {
      //      foundRecord = true;
      //    }
      //  }
      //  return foundRecord;
      //}

			#endregion






    public static DbaseFileReader Create(string filename)
    {
      if (filename == null)
        throw new ArgumentNullException(filename);

      // check for the file existing here, otherwise we will not get an error
      if (!File.Exists(filename))
        throw new FileNotFoundException(String.Format("Could not find file \"{0}\"", filename));

      return new DbaseFileReader(filename);

    }

 


	}
}
